﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Collections;
using Ict.DataAccess;
using Ict.DataAccess.Conditions;

namespace Ict.DataAccess.SqlServer
{
    /// <summary>
    /// DmlBuilder的MS Sql Server版本
    /// </summary>
    class SqlDmlBuilder : DmlBuilder
    {
        #region IDmlBuilder members

        /// <summary>
        /// 执行一条非查询的SQL语句
        /// </summary>
        /// <param name="sql">非查询的SQL语句</param>
        /// <returns>受影响行数</returns>
        public override string BuildQuery(string[] fieldList, string tableName, Condition condition, params Sort[] sortings)
        {
            string sql = "SELECT " + BuildFieldList(fieldList) + " FROM " + tableName;

            // 如果条件不为空，则生成并附加条件子句
            if (condition != null)
            {
                string sCond = BuildCondition(condition);
                if (sCond != null && sCond != "")
                    sql += " WHERE " + BuildCondition(condition);
            }

            // 如果排序方式不为空，则生成并附加排序子句
            if (sortings != null && sortings.Length > 0)
                sql += BuildSorting(sortings);

            return sql;
        }

        /// <summary>
        /// 构造插入语句
        /// </summary>
        /// <param name="data">待插入的数据</param>
        /// <param name="tableName">表名</param>
        /// <returns>插入语句</returns>
        public override string BuildInsert(DataEntity data, string tableName)
        {
            Dictionary<string, object> values = data.AssignValues;

            if (values.Count > 0)
            {
                IEnumerator ikey = values.Keys.GetEnumerator();
                ikey.MoveNext();
                IEnumerator ivalue = values.Values.GetEnumerator();
                ivalue.MoveNext();

                string sql = "INSERT INTO " + tableName + "(" + (string)(ikey.Current);
                string valueList = " VALUES(" + EncodeValue(ivalue.Current);

                while (ikey.MoveNext())
                {
                    sql += ", " + (string)(ikey.Current);
                    ivalue.MoveNext();
                    valueList += ", " + EncodeValue(ivalue.Current);
                }
                sql += ")" + valueList + ")";
                return sql;
            }
            else
                throw new Exception("No value is assigned.");
        }

        /// <summary>
        /// 构造更新语句
        /// </summary>
        /// <param name="data">待更新的数据</param>
        /// <param name="tableName">表名</param>
        /// <param name="condition">更新条件</param>
        /// <returns>更新语句</returns>
        public override string BuildUpdate(DataEntity data, string tableName, Condition condition)
        {
            Dictionary<string, object> values = data.AssignValues;
            if (values.Count > 0)
            {
                IEnumerator ikey = values.Keys.GetEnumerator();
                ikey.MoveNext();
                IEnumerator ivalue = values.Values.GetEnumerator();
                ivalue.MoveNext();

                string sql = "UPDATE " + tableName + " SET " + (string)(ikey.Current) + "=" + EncodeValue(ivalue.Current);
                while (ikey.MoveNext())
                {
                    ivalue.MoveNext();
                    sql += ", " + (string)(ikey.Current) + "=" + EncodeValue(ivalue.Current);
                }
                if (condition != null)
                    sql += " WHERE " + BuildCondition(condition);
                return sql;
            }
            else
                throw new Exception("No value is assigned.");
        }

        /// <summary>
        /// 构造删除语句
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="condition">删除条件</param>
        /// <returns>删除语句</returns>
        public override string BuildDelete(string tableName, Condition condition)
        {
            string sql = "DELETE FROM " + tableName;
            if (condition != null)
                sql += " WHERE " + BuildCondition(condition);
            return sql;
        }

        #endregion IDmlBuilder members

        private string BuildFieldList(string[] fieldList)
        {
            if (fieldList == null || fieldList.Length == 0)
                return "*";
            else
            {
                IEnumerator i = fieldList.GetEnumerator();
                i.MoveNext();
                string sql = i.Current as string;
                while (i.MoveNext())
                {
                    sql += ", " + i.Current as string;
                }
                return sql;
            }
        }
    }
}
